我們在 [Day7] Lex - Error Handling 的時候,有提到在 lex 中如何處理不在預期的輸入字串。
在yacc的規則匹配期間,我們一樣可以用 yyerror
這個 function 來處理不符合規則的情況。
由於 lex & yacc 是共用同一個 yyerror
,因此小心不要重複定義啦!
那麼,如果出現嚴重的錯誤,有辦法讓Yacc提前終止嗎?
這裡我們可以用 YYABORT
來辦到這件事。
它會直接結束 yyparse()
並回傳一個非零值,表示失敗。
請根據昨天的範例(簡易計算機6),將除法規則中,遇到除數為0的情況下,輸出錯誤訊息,並提前終止計算機。
expr:
value { $$ = $1; }
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr
{
if ($3 == 0.0) {
yyerror("Error: divisor cannot be zero!");
YYABORT;
} else {
$$ = $1 / $3;
}
}
| '-' expr %prec UMINUS { $$ = -$2; }
| '(' expr ')' { $$ = $2; }
;
-27.84 / 0 =
Error: divisor cannot be zero!
經過今天的介紹,我們已經有辦法在 lex & yacc 中都能做到錯誤訊息的處理,避免程式跑到一半就crash了。